package com.mrd.gtimpframe.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.mrd.gtimp.base.entity.User;
import com.mrd.gtimpframe.entity.TGenDeclaInsGroupRef;
import com.mrd.gtimpframe.entity.TGenDeclaInspectRule;
import com.mrd.gtimpframe.entity.TGenDeclaInspectRuleRe;
import com.mrd.gtimpframe.entity.TGenDeclaPolicyRules;
import com.mrd.gtimpframe.remote.PolicyRulesParam;
import com.mrd.gtimpframe.repository.TGenDeclaInsGroupRefMapper;
import com.mrd.gtimpframe.repository.TGenDeclaInspectRuleMapper;
import com.mrd.gtimpframe.repository.TGenDeclaInspectRuleReMapper;
import com.mrd.gtimpframe.repository.TGenDeclaPolicyRulesMapper;
import com.mrd.gtimpframe.service.TGenDeclaPolicyRulesService;
import com.mrd.util.KeyGenerator;


@Service("tGenDeclaPolicyRulesService")
public class TGenDeclaPolicyRulesServiceImpl implements TGenDeclaPolicyRulesService {
  @Autowired
  TGenDeclaPolicyRulesMapper tGenDeclaPolicyRulesMapper;
  @Autowired
  TGenDeclaInsGroupRefMapper tGenDeclaInsGroupRefMapper;
  @Autowired
  TGenDeclaInspectRuleReMapper tGenDeclaInspectRuleReMapper;
  @Autowired
  TGenDeclaInspectRuleMapper tGenDeclaInspectRuleMapper;

  @Override
  @Transactional
  public int deleteByPrimaryKey(Object id) {
    return tGenDeclaPolicyRulesMapper.deleteByPrimaryKey(id);
  }

  @Override
  @Transactional
  public int insert(TGenDeclaPolicyRules declaPolicyRules) {
    if (StringUtils.isEmpty(declaPolicyRules.getId())) {
      declaPolicyRules.setId(KeyGenerator.generateSequenceNo());
    }
    return tGenDeclaPolicyRulesMapper.insert(declaPolicyRules);
  }

  @Override
  @Transactional
  public int insertSelective(TGenDeclaPolicyRules declaPolicyRules) {
    if (StringUtils.isEmpty(declaPolicyRules.getId())) {
      declaPolicyRules.setId(KeyGenerator.generateSequenceNo());
    }
    return tGenDeclaPolicyRulesMapper.insertSelective(declaPolicyRules);
  }

  @Override
  public TGenDeclaPolicyRules selectByPrimaryKey(Object id) {
    return tGenDeclaPolicyRulesMapper.selectByPrimaryKey(id);
  }

  @Override
  @Transactional
  public int updateByPrimaryKeySelective(TGenDeclaPolicyRules t) {
    return tGenDeclaPolicyRulesMapper.updateByPrimaryKeySelective(t);
  }

  @Override
  @Transactional
  public int updateByPrimaryKey(TGenDeclaPolicyRules t) {
    return tGenDeclaPolicyRulesMapper.updateByPrimaryKey(t);
  }

  public List<TGenDeclaPolicyRules> queryList(TGenDeclaPolicyRules tGenDeclaPolicyRules) {
    return tGenDeclaPolicyRulesMapper.queryList(tGenDeclaPolicyRules);
  }

  /**
   * 数据关系转换为页面模型关系
   * 
   * @author han
   */
  public PolicyRulesParam.PolicyRules policyData(String id) {
    PolicyRulesParam.PolicyRules rtnRule = new PolicyRulesParam.PolicyRules();
    TGenDeclaPolicyRules tGenDeclaPolicyRules = tGenDeclaPolicyRulesMapper.selectByPrimaryKey(id);
    rtnRule = dataPolicyChange(tGenDeclaPolicyRules);
    return rtnRule;
  }

  /**
   * 保存政策提醒，包括组下面的子规则
   * 
   * @author han
   */
  @Transactional
  public void savePolicyRules(PolicyRulesParam.PolicyRules policyRules, User user) {
    Date modifyTime = new Date();// 修改时间
    String modifier = "";// 修改人
    Date createTime = new Date();// 创建时间
    String creator = "";// 创建人
    if (StringUtils.isEmpty(policyRules.getPruleId())) {
      policyRules.setPruleId(KeyGenerator.generateRadomSequenceNo("rule_"));
      if (user != null)
        creator = user.getName();// 创建人
    } else {
      TGenDeclaPolicyRules rtnRule =
          tGenDeclaPolicyRulesMapper.selectByPrimaryKey(policyRules.getPruleId());
      createTime = rtnRule.getCreateTime();// 创建时间-
      creator = rtnRule.getCreator();// 创建人
      if (user != null)
        modifier = user.getName();// 修改人
      Object[] pruleIds = new Object[1];
      pruleIds[0] = policyRules.getPruleId();
      tGenDeclaPolicyRulesMapper.deleteByPrimaryKey(policyRules.getPruleId());
      tGenDeclaInsGroupRefMapper.deleteBatchByPolicyId(pruleIds);
      tGenDeclaInspectRuleReMapper.deleteBatchByPolicyId(pruleIds);
      tGenDeclaInspectRuleMapper.deleteBatchByPolicyId(pruleIds);
    }
    // 先把入参对象化转换成数据库关系对象，保存
    TGenDeclaPolicyRules tGenDeclaPolicyRules = policyRules.PolicyRulesToTGenDeclaPolicyRules();
    tGenDeclaPolicyRules.setCreateTime(createTime);
    tGenDeclaPolicyRules.setCreator(creator);
    tGenDeclaPolicyRules.setModifier(modifier);
    tGenDeclaPolicyRules.setModifyTime(modifyTime);
    tGenDeclaPolicyRulesMapper.insert(tGenDeclaPolicyRules);
    List<PolicyRulesParam.Group> listGroup = policyRules.getListRule();
    for (int i = 0; i < listGroup.size(); i++) {
      PolicyRulesParam.Group group = listGroup.get(i);
      String combiMethod = group.getCombiMethod();

      TGenDeclaInsGroupRef tGenDeclaInsGroupRef = new TGenDeclaInsGroupRef();
      tGenDeclaInsGroupRef.setPolicyRulesId(policyRules.getPruleId());
      tGenDeclaInsGroupRef.setId(KeyGenerator.generateRadomSequenceNo("groupRef_"));
      tGenDeclaInsGroupRef.setPolicyRulesId(tGenDeclaPolicyRules.getId());

      if (i > 0) {
        // 存组与组的关系
        tGenDeclaInsGroupRef.setCombiMethod(combiMethod);
        tGenDeclaInsGroupRef.setGroupIndex1(new BigDecimal(i - 1));
        tGenDeclaInsGroupRef.setGroupIndex2(new BigDecimal(i));
        // save
        tGenDeclaInsGroupRefMapper.insert(tGenDeclaInsGroupRef);
      } else {
        // 单个组,第一个组，不做操作处理
      }

      // 细规则
      List<PolicyRulesParam.Rule> rules = group.getList();
      for (int j = 0; j < rules.size(); j++) {
        String ruleCombiMethod = rules.get(j).getCombiMethod();
        TGenDeclaInspectRule spectRule = rules.get(j).ruleToTGenDeclaInspectRule();
        spectRule.setRefGroup(new BigDecimal(i));
        spectRule.setStatus("0");
        spectRule.setPolicyRulesId(tGenDeclaPolicyRules.getId());
        tGenDeclaInspectRuleMapper.insert(spectRule);
        if (j > 0) {
          TGenDeclaInspectRuleRe tGenDeclaInspectRuleRe = new TGenDeclaInspectRuleRe();
          PolicyRulesParam.Rule beforRule = rules.get(j - 1);
          tGenDeclaInspectRuleRe.setId(KeyGenerator.generateRadomSequenceNo("ruleRe_"));
          tGenDeclaInspectRuleRe.setCombinationMethod(ruleCombiMethod);
          tGenDeclaInspectRuleRe.setRuleId1(beforRule.getRuleId());
          tGenDeclaInspectRuleRe.setRuleId2(rules.get(j).getRuleId());
          tGenDeclaInspectRuleRe.setPolicyRulesId(tGenDeclaPolicyRules.getId());
          tGenDeclaInspectRuleReMapper.insert(tGenDeclaInspectRuleRe);
        }
      }
    }
  }

  /**
   * 根据场景转换规则关系
   * 
   * @author han
   * @param bizSceneId 场景主键
   */
  @Override
  public List<PolicyRulesParam.PolicyRules> getSceenPolicyRule(String bizSceneId) {
    List<PolicyRulesParam.PolicyRules> policyRulesList =
        new ArrayList<PolicyRulesParam.PolicyRules>();
    List<TGenDeclaPolicyRules> declaPolicyRulesList =
        tGenDeclaPolicyRulesMapper.selectByBizScene(bizSceneId);
    if (declaPolicyRulesList != null && declaPolicyRulesList.size() > 0) {
      for (TGenDeclaPolicyRules itemPolicyRule : declaPolicyRulesList) {
        PolicyRulesParam.PolicyRules rtnRule = new PolicyRulesParam.PolicyRules();
        rtnRule = dataPolicyChange(itemPolicyRule);
        policyRulesList.add(rtnRule);
      }
    }
    return policyRulesList;
  }

  /**
   * 单条验证规则转换器
   * 
   * @author han
   * @param tGenDeclaPolicyRules
   * @param rtnRule
   */
  public PolicyRulesParam.PolicyRules dataPolicyChange(TGenDeclaPolicyRules tGenDeclaPolicyRules) {
    PolicyRulesParam.PolicyRules rtnRule = new PolicyRulesParam.PolicyRules();
    List<TGenDeclaInsGroupRef> listGroupRef = tGenDeclaPolicyRules.getInsGroupRef();
    List<TGenDeclaInspectRuleRe> listRuleRe = tGenDeclaPolicyRules.getInspectRuleRef();
    List<TGenDeclaInspectRule> listRules = tGenDeclaPolicyRules.getTnspectRules();

    List<PolicyRulesParam.Group> rtnGroupList = new ArrayList<PolicyRulesParam.Group>();// 规则组和规则关系
    Map<String, PolicyRulesParam.Group> groupMap = new HashMap<String, PolicyRulesParam.Group>();
    if (tGenDeclaPolicyRules != null) {
      rtnRule = new PolicyRulesParam.PolicyRules().PolicyRules(tGenDeclaPolicyRules);
      if (listRules != null) {
        for (TGenDeclaInspectRule tGenDeclaInspectRule : listRules) {
          PolicyRulesParam.Rule itemRule =
              new PolicyRulesParam.Rule().TGenDeclaInspectRuleToRule(tGenDeclaInspectRule);

          String groupId = tGenDeclaInspectRule.getRefGroup().toString();
          // 遍历规则关系表
          for (TGenDeclaInspectRuleRe tGenDeclaInspectRuleRe : listRuleRe) {
            if (tGenDeclaInspectRuleRe.getRuleId2().equals(itemRule.getRuleId())) {
              itemRule.setCombiMethod(tGenDeclaInspectRuleRe.getCombinationMethod());
              break;
            }
          }
          if (groupMap.containsKey(groupId)) {
            PolicyRulesParam.Group mapGroup = groupMap.get(groupId);
            mapGroup.getList().add(itemRule);
          } else {
            PolicyRulesParam.Group newGroup = new PolicyRulesParam.Group();
            newGroup.setGroupId(groupId);
            newGroup.getList().add(itemRule);
            groupMap.put(groupId, newGroup);
          }
        }
      }
      for (String key : groupMap.keySet()) {
        PolicyRulesParam.Group mapGrop = groupMap.get(key);
        for (TGenDeclaInsGroupRef tGenDeclaInsGroupRef : listGroupRef) {
          if (tGenDeclaInsGroupRef.getGroupIndex2().toString().equals(key)) {
            mapGrop.setCombiMethod(tGenDeclaInsGroupRef.getCombiMethod());
            break;
          }
        }
        rtnGroupList.add(mapGrop);
      }
      rtnRule.setListRule(rtnGroupList);
    }
    return rtnRule;
  }

  /**
   * 批量删除
   * 
   * @author han
   * @param id
   * @return
   */
  @Transactional
  public int deleteBatch(Object[] id) {
    tGenDeclaPolicyRulesMapper.deleteBatch(id);
    tGenDeclaInsGroupRefMapper.deleteBatchByPolicyId(id);
    tGenDeclaInspectRuleReMapper.deleteBatchByPolicyId(id);
    tGenDeclaInspectRuleMapper.deleteBatchByPolicyId(id);
    return 0;
  }

  /**
   * 根据规则主键查询场景编码
   * 
   * @author han
   * @param id
   * @return
   */
  public List<String> queryRuleIDsBizScene(String[] ids) {
    return tGenDeclaPolicyRulesMapper.queryRuleIDsBizScene(ids);
  }
}
